package ymap

import "sync"

type ISet[V any] interface {

	// set as default value
	SetDefault(value V)

	// set pair key-value
	Set(key string, value V)

	// get default value
	GetDefault() (V, bool)

	// get value by key
	Get(key string) (V, bool)

	// delete key
	Delete(key string)

	// get all keys
	Keys() []string

	// get all values
	Values() []V
}

func NewSetMap[V any]() ISet[V] {
	return &setMap[V]{
		defaultKey: "*",
	}
}

func NewSetMapAny() ISet[any] {
	return NewSetMap[any]()
}

type setMap[V any] struct {
	defaultKey string // default key
	container  sync.Map
}

// Delete implements ISet.
func (s *setMap[V]) Delete(key string) {
	s.container.Delete(key)
}

// Get implements ISet.
func (s *setMap[V]) Get(key string) (V, bool) {
	value, ok := s.container.Load(key)
	if !ok {
		return *new(V), false
	}
	return value.(V), true
}

// GetDefault implements ISet.
func (s *setMap[V]) GetDefault() (V, bool) {
	return s.Get(s.defaultKey)
}

// Keys implements ISet.
func (s *setMap[V]) Keys() []string {
	keys := make([]string, 0)
	s.container.Range(func(key, _ any) bool {
		keys = append(keys, key.(string))
		return true
	})
	return keys
}

// Set implements ISet.
func (s *setMap[V]) Set(key string, value V) {
	s.container.Store(key, value)
}

// SetDefault implements ISet.
func (s *setMap[V]) SetDefault(value V) {
	s.Set(s.defaultKey, value)
}

// Values implements ISet.
func (s *setMap[V]) Values() []V {
	values := make([]V, 0)
	s.container.Range(func(_, value any) bool {
		values = append(values, value.(V))
		return true
	})
	return values
}
